#include <iostream>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "InetAddr.hpp"
#include "Socket.hpp"
#include "LogMessage.hpp"
#include "Protocol.hpp"

void Usage()
{
    std::cout << "Please enter: ./Client ip port" << std::endl;
}


int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage();
        return 4;
    }
    std::string ip = argv[1];
    uint16_t port = atoi(argv[2]);

    TcpSocket sockfd;
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    addr.sin_port = htons(port);
    InetAddr peer(addr);
    if (sockfd.CreateSocketAndConnect(peer) == false)
    {
        return 5;
    }

    std::string oper = "+-*/%@!#$&=[]";
    srand(time(nullptr) ^ getpid());
    Protocol::Factory fact;

    std::string send;
    while (true)
    {
        int x = rand() % 100;
        usleep(rand() % 1234);
        int y = rand() % 100;
        usleep(rand() % 321);
        char op = oper[rand() % oper.size()];

        auto req = fact.BulidRequest(x, op, y);
        std::string request;
        req->Serialization(&request);
        std::string total = std::to_string(request.size()) + "\n" + request + "\n";
        std::cout << total << std::endl;

        sockfd.Sendto(total, peer);

        std::string recv;
Start:
        sockfd.Recvfrom(recv, &peer);
        int left = recv.find("\n");
        if (left == std::string::npos)
        {
            goto Start;
        }

        int right = recv.find("\n", left + 1);
        if (right == std::string::npos)
        {
            goto Start;
        }
        //必须确保读到了一个完整的协议
        std::string result = recv.substr(left + 1, right - left - 1);
        std::cout << request << " = " << result << std::endl;

        sleep(1);
    }

    return 0;
}